package com.be.beadmin.basicData.impl;

import cn.hutool.core.util.ObjectUtil;
import com.alibaba.druid.util.StringUtils;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.be.beadmin.basicData.dto.input.MenuDto;
import com.be.beadmin.basicData.dto.input.MenuParentFilter;
import com.be.beadmin.basicData.dto.output.MenuEx;
import com.be.beadmin.basicData.entity.Menu;
import com.be.beadmin.basicData.entity.Menu_;
import com.be.beadmin.basicData.entity.Role_;
import com.be.beadmin.basicData.mapper.MenuDtoMapper;
import com.be.beadmin.basicData.mapper.MenuMapper;
import com.be.beadmin.basicData.repository.MenuRepository;
import com.be.beadmin.basicData.service.MenuService;

import com.be.beadmin.common.exception.BeadminException;


import com.be.beadmin.common.utils.JpaQueryBuilder;
import com.be.beadmin.common.utils.JpaQueryBuilderNew;
import com.be.beadmin.common.utils.JpaSortBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;

import javax.persistence.criteria.Order;
import javax.persistence.criteria.Predicate;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service
public class MenuServiceImpl implements MenuService {

    public String MENU_TITLE = "title";

    public String MENU_KEY = "key";

    public String MENU_CHILDREN = "children";

    @Autowired
    MenuRepository menuRepository;

    @Autowired
    MenuMapper menuMapper;

    @Autowired
    MenuDtoMapper menuDtoMapper;

    @Override
    public Page<MenuEx> getMenuByPage(MenuParentFilter menuParentFilter) {
        Pageable pageable = PageRequest.of(
                menuParentFilter.getCurrent() -1,
                menuParentFilter.getPageSize());
        Page<Menu> page = menuRepository.findAll((root, criteriaQuery, criteriaBuilder) -> {
                    List<Predicate> list = new ArrayList<>();
                    Predicate pre1 =   JpaQueryBuilderNew.getPredicate(root, menuParentFilter.getFilters(), criteriaBuilder);
                    list.add(pre1);
                    Predicate pre2 = criteriaBuilder.equal(root.get(Menu_.delete), 0); //过滤为0
                    list.add(pre2);

                    if (!StringUtils.isEmpty(menuParentFilter.getParentId())) {
                        // 级联查询
                        Predicate pre3 = criteriaBuilder.equal(root.get(Menu_.parentMenu).get(Menu_.id), menuParentFilter.getParentId()); //过滤为0
                        list.add(pre3);
                    }
                    Predicate[] p = new Predicate[list.size()];
                    List<Order> orders = new ArrayList<>();
                    if(menuParentFilter.getSorters() != null && menuParentFilter.getSorters().size() > 0) {
                        orders = JpaSortBuilder.getPredicate(root, menuParentFilter.getSorters(), criteriaBuilder);
                        criteriaQuery.orderBy(orders);
                    } else {
                        criteriaQuery.orderBy(criteriaBuilder.desc(root.get(Role_.createTime).as(Date.class)));
                    }
                    return  criteriaBuilder.and(list.toArray(p));
                }
                , pageable);
        Page<MenuEx> page1 = page.map(menuMapper::toEntity);
        return page1;

    }

    @Override
    public JSONArray getMenuTree() {

        JSONArray result = new JSONArray(); // 最终返回

        // 虚拟顶层菜单
        JSONObject virtualTop = new JSONObject();
        virtualTop.put(MENU_TITLE,"菜单树");
        virtualTop.put(MENU_KEY,"");

        // 多个目录树 获取顶层菜单数据
        List<Menu> menus =  menuRepository.findMenusByDeleteAndParentMenuOrderBySeq(0,null);

        JSONArray arr = new JSONArray();
        for(Menu menu : menus){
            JSONObject object = recursiveMenu(menu);
            arr.add(object);
        }
        virtualTop.put(MENU_CHILDREN,arr);
        result.add(virtualTop);
        return result;
    }

    @Override
    public void addMenu(MenuDto menuDto) {

        Menu temp = menuRepository.findMenuByCodeAndDelete(menuDto.getCode(), 0);
        if (ObjectUtil.isNotEmpty(temp)) {
            throw new BeadminException("该编码已经存在不要重复提交");
        }

        Menu parent = menuRepository.findMenuById(menuDto.getParentId());

        Menu menu = menuDtoMapper.toEntity(menuDto);
        menu.setParentMenu(parent);
        Integer seq;
//        if(parent!=null){
//            seq = menuRepository.queryMaxSeqByParentMenuId(parent.getId()) + 1;
//        }else{
//            seq = menuRepository.queryMaxSeqByParentMenuIsNull() + 1;
//        }
//        menu.setSeq(seq);
        menuRepository.save(menu);
    }

    @Override
    public void updateMenu(MenuDto menuDto) {

        Menu menu = menuRepository.findMenuById(menuDto.getId());
        menu.setName(menuDto.getName());
//        menu = menuDtoMapper.toEntity(menuDto);
        Menu result = menuRepository.save(menu);

    }

    @Override
    public void delMenu(MenuDto menuDto) {
        Menu menu = menuRepository.findMenuById(menuDto.getId());
        menu.setDelete(1);
        menuRepository.save(menu);
    }

    @Override
    public void delMenus(List<MenuDto> menuDtos) {

    }

    public JSONObject recursiveMenu(Menu menu){
        JSONObject object = new JSONObject();
        object.put(MENU_TITLE,menu.getName());
        object.put(MENU_KEY,menu.getId());
//        object.put("spread",false);
        if(menu.getChildMenus().size()>0){
            JSONArray children = new JSONArray();
            for(Menu child : menu.getChildMenus()){
                JSONObject obj = recursiveMenu(child);
                children.add(obj);
            }
            object.put(MENU_CHILDREN,children);
        }
        return object;
    }
}
